/**
 *******************************************************************************
 * @FileName  : sys_time.h
 * @Author    : GaoQiu
 * @CreateDate: 2020-02-18
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */

#ifndef SYS_TIME_H_
#define SYS_TIME_H_

#include "defs_types.h"
#include "platform/platform.h"
#include "assert.h"
#include "stack/controller/bb_api.h"
#include "stack/controller/bb.h"

#define SYS_TIME_SRC       TIMER0
#define SYS_TIME_RATE_MHZ  16   // in MHz

#ifdef IP_108
	#define SYS_TIME_TICK_PER_US      SYS_TIME_RATE_MHZ   //???
	#define SYS_TIME_TICK_TO_US(tick) BB_TICK_TO_US(tick)
	#define SYS_TIME_US_TO_TICK(us)   BB_US_TO_TICK(us)
	#define SYS_TIME_MS_TO_TICK(ms)   BB_US_TO_TICK(ms * 1000)
#elif defined(IP_107)
	#define SYS_TIME_TICK_PER_US      SYS_TIME_RATE_MHZ
    #define SYS_TIME_TICK_TO_US(tick) (tick / SYS_TIME_TICK_PER_US)
	#define SYS_TIME_US_TO_TICK(us)   ((us) * SYS_TIME_TICK_PER_US)
	#define SYS_TIME_MS_TO_TICK(ms)   SYS_TIME_US_TO_TICK(ms * 1000)
#endif


#define SystemTimeInit()                  SysTimeInit()
#define GetSysTimeTick()                  SysTime_GetCurTick()
#define IsSysTimeExpired(refTick, us)     SysTime_IsTimeExpired(refTick, us)


static _inline_ void SysTimeInit(void)
{
#ifdef IP_108
	if(!BB_IsTimerEnabled()){
		//bbCb.sleepClockSrc = CFG_SLEEP_CLOCK_SOURCE;
		//BB_Calibrate32kRC(32000);
		BB_SetTimerEnable(1);
	}
#elif defined(IP_107)
	CLK_APB1PeriphClockCmd(CLK_APB1Periph_TMR0, ENABLE);
	SYS_TIME_SRC->CTL = 0;
	SYS_TIME_SRC->CTL = BIT(30)| (3<<27) | 2;
#endif
}

static _inline_ uint32_t SysTime_GetCurTick(void)
{
#ifdef IP_108
	return BB_GetCurTick();
#else
	return SYS_TIME_SRC->CNT;
#endif
}

static _inline_ void SysTime_SetCurCmp(uint32_t cmp) //compare
{
	SYS_TIME_SRC->CMP = cmp;
}

static _inline_ uint32_t SysTime_GetCurCmp(void)
{
	return SYS_TIME_SRC->CMP;
}

static _inline_ void SysTime_EnableIrq(void)
{
	SYS_TIME_SRC->CTL |= BIT(29);
	//NVIC_EnableIRQ(TMR0_IRQn);
}

static _inline_ void SysTime_DisableIrq(void)
{
	SYS_TIME_SRC->CTL &= ~BIT(29);
	//NVIC_DisableIRQ(TMR0_IRQn);
}

static _inline_ bool_t SysTime_GetIrqState(void)
{
	return SYS_TIME_SRC->INTSTS & BIT(0);
}

static _inline_ void SysTime_ClearIrqState(void)
{
	SYS_TIME_SRC->INTSTS |= BIT(0); // TIF= Timer Interrpt Flag, w1c0
}

static _inline_ bool_t SysTime_IsTimeExpired(uint32_t refTick, uint32_t us)
{
#ifdef IP_108
	return BB_IsTimeExpired(refTick, us);
#elif defined(IP_107)
	uint32_t nowTick = SysTime_GetCurTick();
	return ((uint32_t)(nowTick - refTick) >= (us * SYS_TIME_TICK_PER_US));
#endif
}

void delay_us(uint32_t us);
void delay_ms(uint16_t ms);

#endif /* SYS_TIME_H_ */
